#ifndef ATTR_PROB_H
#define ATTR_PROB_H
#include <vector>
#include <algorithm>
#include <iterator>
#include "attribute.h"
#include "attribute_info.h"

//===============================================
//Class: attr_prob
//       This class is the structure to store the 
//       infomation which we used in naive bayes 
//       calssifier.
//Author:Junix <unix_jun@yahoo.com.cn>
//==============================================

class attr_prob
{
public:
//====================================================
//   construct and deconstruct
//====================================================
    attr_prob ()
    {
        _id = 0;
        _type = ATTR_DISCRETE;
    }

    attr_prob (int id, vector < attribute_info > *infos)
    {
        init_map (id, infos);
    }

//initialize the coef  struture to 0.
//make ready to count.
    int init_map (int id, vector < attribute_info > *infos)
    {
        _id = id;
        _type = infos->at (id).type ();
        if (_type == ATTR_DISCRETE)
        {
            string item, prefix, postfix;
            for (int i = 0; i < infos->at (id)._range.size (); i++)
            {
                prefix = infos->at (id)._range.at (i);
                for (int j = 0; j < infos->back()._range.size (); j++)
                {
                    postfix = infos->back()._range.at (j);
                    item = prefix + "|" + postfix;
                    _discrete_attr_map.insert (std::make_pair (item, 0));
                }
                    _discrete_attr_map.insert (std::make_pair (prefix, 0));
            }
        }
        else
        {
            string item, postfix;
            for (int j = 0; j < infos->back()._range.size (); j++)
            {
                postfix = infos->back()._range.at (j);
                item = "mu|" + postfix;
                _numeric_attr_map.insert (std::make_pair (item, 0));
                item = "sigma|" + postfix;//here sigma means sigma*sigma
                _numeric_attr_map.insert (std::make_pair (item, 0));
            }
                //here  mean and  variance of all the attribution
                _numeric_attr_map.insert (std::make_pair ("mu", 0));
                _numeric_attr_map.insert (std::make_pair ("sigma", 0));

        }
    }
 
 
//===================================================
//  Print
//===================================================
    friend ostream& operator<<(ostream& os, const attr_prob& atpr)
    {
        os<<"attribution: "<<atpr._id<<std::endl;
        if (atpr._type==ATTR_DISCRETE)
        {
            map<string,int>::const_iterator iter=atpr._discrete_attr_map.begin();
            while (iter!=atpr._discrete_attr_map.end())
            {
                os<<iter->first<<": "<<iter->second<<endl;
                iter++;
            }
        }
        else
        {
             map<string,float>::const_iterator iter=atpr._numeric_attr_map.begin();
            while (iter!=atpr._numeric_attr_map.end())
            {
                os<<iter->first<<": "<<iter->second<<endl;
                iter++;
            }
        }
	os<<endl<<endl;
    }

//================================================
//     MEMBER
//================================================
        int _id;
        int _type;
        map < string, int >     _discrete_attr_map;
        map < string, float >    _numeric_attr_map;
    };

#endif
